#include "app_bt.h"

static char bt_send_hear[8] = {0x41, 0x54, 0x2b, 0x4d, 0x45, 0x53, 0x48, 0x00};
static char bt_send_tail[2] = {0x0d, 0x0a};
static char bt_receive_header[2]={0xf1,0xdd };

/**
 * @brief 蓝牙初始化配置
 * 1 设置 预处理方法 2个  写前 读后
 * 2 设置 蓝牙相关的参数的默认值 波特率 网络id 网络短地址 网络名称
 * 
 */
int app_bt_init(device_t *device)
{
    device->per_write = app_bt_per_write;
    device->post_read = app_bt_post_read;
    return 0;
}


/**
 * @brief 蓝牙写前预处理
 * @param data 处理前的数据
 * @param data_len 处理前的数据长度
 * @return 处理后数据的长度
 * 
 */

/**
 *
  把字节数组转换为蓝牙数据
   * 准备向设备写前处理数据来满足蓝牙发送数据的要求
 * 当前data: conn_type id_len msg_len id msg (01 02 03 ff ff 11 22 33)
 * 蓝牙发送数据格式:  41 54 2b 4d 45 53 48 00 ff ff 11 22 33 0d 0a
  示例：41 54 2b 4d 45 53 48 00 ff ff 41 42 43 0d 0a
        41 54 2b 4d 45 53 48 00： AT+MESH（固定头部）
        ff ff: 对端的MADDR（如果是FFFF代表群发）
        11 22 33: 要发送的数据（不超过12字节）
        0d 0a：\r\n（固定结尾）
*/

int app_bt_per_write(char *data, int data_len)
{
    char data_new[100];
    int id_len = data[1];
    int msg_len = data[2];

    // 帧头
    memcpy(data_new,bt_send_hear,8);
    // id
    memcpy(data_new+8,data+3,id_len);
    // msg
    memcpy(data_new+8+id_len,data+3+id_len,msg_len);
    // 帧尾
    memcpy(data_new+8+id_len+msg_len,bt_send_tail,2);
    
    // 覆盖原始数据
    int data_new_len = 8+id_len+msg_len+2;
    memcpy(data,data_new,data_new_len);
    return data_new_len;
}


/**
 * @brief 蓝牙读后预处理
 * @param data 处理前的数据
 * @param data_len 处理前的数据长度
 * @return 处理后数据的长度
 * 
 */

/**
 *  读后预处理
 *
 * 读取蓝牙中的数据  转换为 字节数组
 *
 * 从设备读取数据后处理数据来满足网关应用的要求
 * 接收方得到数据1（4）：ok\r\n
 * 接收方得到数据2（3 + [2]）：f1 dd 07 23 23 ff ff 41 42 43
    f1 dd : 固定的头部
    07： 之后数据的长度（5-16之间）
    23 23：对端（发送方）的MADDR
    ff ff: 我的MADDR或ffff(群发)
    41 42 43：发送的数据
 * 处理后的数据格式：conn_type id_len msg_len id msg

从设备读取数据后处理数据来满足网关应用的要求
 * 接收方得到数据1（4）：ok\r\n
 * 接收方得到数据2（3 + [2]）：f1 dd 07 23 23 ff ff 41 42 43
    f1 dd : 固定的头部
    07： 之后数据的长度（5-16之间）
    23 23：对端（发送方）的MADDR
    ff ff: 我的MADDR或ffff(群发)
    41 42 43：发送的数据
    转换为：01 02 03 23 23 41 42 43  conn_type id_len msg_len id msg
	//1   把收到的数据加入缓冲区 
	//2   先看当前缓冲区总数据量够不够 至少要有8个字节
	//3   如果够8 个字节 
     //4  从缓冲区中逐个找到帧头 f1 dd
	 //5  如果找到帧头  清理掉帧头之前的数据
	 //6  清理后是否够8个字节 取帧头后的第一个字节 标识了之后数据的长度 根据此长度判断当前q缓冲区是否有整帧数据。
	 //7  如果有整帧数据  则把整帧数据拷贝到data中 （需要拼接）
	 //8 把改条数据从缓冲区中删除 调整缓冲区长度
     //9 返回数据长度
 */

static char data_buff[100];
static int data_buff_len=0;

//从缓冲区清理指定长度的数据
static void app_bt_clear_data_buff(int len)
{
	memmove(data_buff,data_buff+len,data_buff_len-len);//平移覆盖
	data_buff_len-=len;
}

int app_bt_post_read(char* data,int data_len)
{
	 //1   把收到的数据加入缓冲区 
	 memcpy(data_buff+data_buff_len,data,data_len);
	 data_buff_len+=data_len;
	 app_common_print_hex(data_buff,data_buff_len);

	//2   先看当前缓冲区总数据量够不够 至少要有8个字节
	if(data_buff_len<8)
	{
		return 0;
	}
	//3   如果够8 个字节 
     //4  从缓冲区中逐个找到帧头 f1 dd
	for (int i = 0; i < data_buff_len-1; i++)
	{	
		 if(data_buff[i]==bt_receive_header[0] 
		 && data_buff[i+1]==bt_receive_header[1])
		 {
				//5  如果找到帧头  清理掉帧头之前的数据
				app_bt_clear_data_buff(i);
		 }
	}
	//6  清理后是否够8个字节 取 第3字节 标识了之后数据的长度 根据此长度判断当前q缓冲区是否有整帧数据。
	//清理后不足8个字节退出
	if(data_buff_len<8) 
	{
		return 0;
	}
	 int len_after_header=data_buff[2];
	if(data_buff_len<3+len_after_header) //如果当前缓冲区不足 2（帧头）+ len_after_header（数据长度）
	{
		return 0;
	}
	//以下存在整帧数据
    //7  如果有整帧数据  则把整帧数据拷贝到data中 （需要拼接）
	 data[0]=CONN_TYPE_BT;
	 data[1]=2;
	 data[2]=len_after_header-4; //减去2个地址长度
	 memcpy(data+3,data_buff+3,2);//id
	 memcpy(data+3+2,data_buff+7,data[2]); //msg

   //8 把改条数据从缓冲区中删除 调整缓冲区长度
     app_bt_clear_data_buff(3+len_after_header);

     //9 返回数据长度
	int new_data_len=3+2+data[2]; // 3个帧头+ id固定2 +msg_len

	return new_data_len;

}